#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <pthread.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <netinet/in.h>
#include <stdbool.h>
/*▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  ▓                          程序初始参量配置信息                              ▓
  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓*/
#define SELF_PORT              1234                                   //定义本机网络通讯端口号
#define WEB_ADDR               "127.0.0.1"                            //定义网管程序地址配置
#define WEB_PORT               4321                                   //定义网管程序端口号
#define BUF_SIZE               2048                                   //定义网络接收数据长度
#define LINK_BAD			   0				                      //定义建链失败
#define LINK_OK			       1				                      //定义建链成功
#define SEND_EN			       1				                      //定义允许发送使能
#define SEND_OFF		       0				                      //定义允许发送禁止
#define SERIAL_MAX_LENTH       221                                    //定义串口接收数据最大长度
#define SERIAL_FAN_LENG        24                                     //定义串口接收风扇管理数据长度
#define SAVA_DATA_LENG         221                                    //定义存储信息数据的最大长度字节数
#define TX_FIFO_LENG		   2048*4			                      //定义缓存发送语音数据FIFO的最大长度
#define	RX_FIFO_LENG		   2048*4			                      //定义接收语音数据FIFO的最大长度
/*※※※※※※※※※※※※※※※※※※※结构体全局变量信息※※※※※※※※※※※※※※※※※※※※*/
/*※※※※※※※※※※※※※※※※※※※发送信息※※※※※※※※※※※※※※※※※※※※*/
struct selftestReport        
{
  unsigned short frameHead = 0x0F00;         //帧头 ==0X0F00     
  unsigned short frameRetain = 0x0000;       //帧保留 ==0000     
  unsigned short GoalId = 0x0B00;            //目的ID ==0B00     
  unsigned short SourceID = 0x0A00;          //源ID ==0A00      
  unsigned short synchronizing = 0xFFF5;     //同步序列 ==FFF5   
  unsigned char frameType = 0x0E;            //帧类型 ==0E 00001110
  unsigned char frameCnt = 0x02;             //帧计数 ==02 00000010
  unsigned char selftestoptioncode = 0xE1;   //自检操作码 ==e1 11100001
  unsigned char selftestdatecode = 0x04;     //自检数据码 ==04    
  unsigned char frameEnd = 0xE9;             //帧尾(即校验和) ==E9=E9
}selftest_report;
/*※※※※※※※※※※※※※※※※※※※接收信息※※※※※※※※※※※※※※※※※※※※*/
struct selftestQuery          
{
  unsigned short frameHead;                         //帧头 ==0X0E00
  unsigned short frameRetain;                       //帧保留 ==0000
  unsigned short GoalId;                            //目的ID ==0A00
  unsigned short SourceID;                          //源ID ==0B00
  unsigned short synchronizing;                     //同步序列 ==FFF5
  unsigned char frameType;                          //帧类型 ==0D
  unsigned char frameCnt;                           //帧计数 ==01
  unsigned char selftestqueryoptioncode;            //自检查询操作码 ==e1
  unsigned char frameEnd;                           //帧尾(即校验和)
}selftest_query;
/*※※※※※※※※※※※※※※※※※※※※※全局变量声明※※※※※※※※※※※※※※※※※※※※※※*/
unsigned char linkCnt = 0;                         //定义建链回执发送帧计数

/*定义UDP套接字*/
int sockfd;
struct sockaddr_in server_addr, client_addr;
struct sockaddr_in dest_addr;
pthread_t receive_tid, send_tid;//定义线程ID
/*********************************************************************
* 函数名称：variableInit  
* 功能描述：默认初始化变量(初始化返回值防止错误数据)
**********************************************************************/
void variableInit(void)					
{
	memset(&selftest_query,0,sizeof(struct selftestQuery));           //清0缓存
}
/*********************************************************************
* 函数名称：recSelftestQuery
* 功能描述：接收指令处理
**********************************************************************/
void recSelftestQuery(void)
{

    if(selftest_query.frameHead == 0x0E && selftest_query.frameType == 0x0D  && selftest_query.frameCnt == 0x01)
	{
       	sendto(sockfd,&selftest_report,sizeof(struct selftestReport),0,(struct sockaddr *)&dest_addr,sizeof(dest_addr));
	}
 
}

/*********************************************************************
* 函数名称：udp_receive_thread
* 功能描述：实现UDP数据的接收处理
**********************************************************************/
static void *udp_receive_thread(void *arg) {   
    unsigned char buffer[BUF_SIZE];
	  unsigned int rx_udp_cnt = 0;
    socklen_t addr_len;
	//创建udp_receive_thread接收线程UDP套接字
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    //设置服务器地址结构
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(SELF_PORT);
    bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));// 绑定套接字
	  addr_len = sizeof(client_addr);
    while(1) {
		if((rx_udp_cnt = recvfrom(sockfd, buffer, BUF_SIZE, 0, (struct sockaddr *)&client_addr, &addr_len)) < 0)
		{perror("recvfrom");}
		printf("Received data: ");
    int i;
    for (i = 0; i < rx_udp_cnt; i++) {
         printf("%02x ", buffer[i]);
			}printf("\n");
    if(rx_udp_cnt == sizeof(struct selftestQuery))
	{
      printf("recive serlftestquery \n");
	  	memcpy(&selftest_query,buffer,rx_udp_cnt);//缓存查询指令数据
	  	recSelftestQuery();//处理指令
	}
	else
	{
      printf("?date? \n");
			rx_udp_cnt = 0;
			memset(&buffer,0, sizeof(buffer));
	}
		usleep(10*1000);
    }
    rx_udp_cnt = 0;
	memset(&buffer,0, sizeof(buffer));
    close(sockfd);
    return NULL;
}
/*********************************************************************
* 函数名称：udp_send_thread
* 功能描述：实现UDP发送线程UDP套接字
**********************************************************************/
static void *udp_send_thread(void *arg) {  
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);//创建udp_send_thread发送线程UDP套接字
    // 设置目标地址结构
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_addr.s_addr = inet_addr(WEB_ADDR); // 发送到地址
    dest_addr.sin_port = htons(WEB_PORT);
    while(1) {
        //sendto(sockfd, message, strlen(message), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));// 发送数据十
		usleep(100*1000);
    }
    close(sockfd);
    return NULL;
}
/*********************************************************************
* 函数名称：main
* 功能描述：主函数，程序入口，完成初始化、装配状态加载和线程创建
**********************************************************************/
int main() {
	variableInit();                                                        //默认初始化变量
    
    if(pthread_create(&send_tid, NULL, udp_send_thread, NULL) == -1)  //创建UDP发送线程
	{
        printf("create CManagement udp_send_thread pthread failed! \n");
        return 0;
    }else printf("create CManagement udp_send_thread pthread succeed! \n");
        
	if(pthread_create(&receive_tid, NULL, udp_receive_thread, NULL) == -1) //创建UDP接收线程
	{
        printf("create CManagement udp_receive_thread pthread failed! \n");
        return 0;
    }else printf("create CManagement udp_receive_thread pthread succeed! \n");
	
    pthread_join(receive_tid, NULL);
    pthread_join(send_tid, NULL); 
	
    return 0;
}



